﻿using System.Collections.Generic;
using System.IO;

namespace Pvf.Core
{

    internal abstract class PvfObjectConverterDispatchWrapper<TSrc> : PvfObjectConverterWrapper
    {
        public abstract void SetValue(BinaryReader reader, TSrc src, IPvfModule module, ref int key);
    }

    internal sealed class PvfObjectConverterDispatchWrapper<TSrc, TProperty, TBase> : PvfObjectConverterDispatchWrapper<TSrc>
    {
        public override void SetValue(BinaryReader reader, TSrc src, IPvfModule module, ref int key)
        {
            if (reader.IsEndOfStream())
            {
                return;
            }

            if (!(Converter is IDynamicElementConverter dynamicElementConverter))
            {
                return;
            }

            var subConverterData = dynamicElementConverter.GetSubConverterData(key);

            if (!(subConverterData.Converter is IBinaryPvfConverter<TBase> binaryPvfConverter)) return;
            
            var value = binaryPvfConverter.Deserialize(reader, module);

            if (value is IDynamicElementEntity entity)
            {
                dynamicElementConverter.SetEntityKey(ref entity, subConverterData);
            }

            if (dynamicElementConverter is IDynamicElementCollectionConverter<TBase> dyCollectionConverter)
            {
                var objColl = Getter(src);

                if (objColl == null)
                {
                    objColl = dyCollectionConverter.CreateEmpty();
                    Setter(src, objColl);
                }

                if (objColl is ICollection<TBase> collection)
                {
                    collection.Add(value);
                }
            }
            else
            {
                Setter(src, value);
            }
        }
    }
}
